스타벅스&이디야 입지환경 분석 & 지하철역 최단거리 분석 PART1¶

In [463]:
Image('title.png')
Out[463]:

스타벅스 인근에 전략적으로 이디야가 입점한다는 말이 있지만, 공식적인 근거는 없어서 이에 대한 다양한 분석들이 이뤄지고 있다.¶

본 분석에서는 입지 환경적 측면, 특히 지하철역과 관련하여 두 브랜드의 위치적 관련성을 분석해 본다. 아래 두 파트로 진행해 보았다.¶

1. 구별 스타벅스 이디야 매장 입지환경 분석 ( 공시지가, 지하철역수, 매장수)¶

( PART2 에서 입지 환경의 다른 분야에 대해 분석 예정 )¶

2. 스타벅스 & 이디야 매장에서 지하철역까지의 최단거리 분석¶

In [458]:
import os 
import geopandas as gpd 
import osmnx as ox 
import networkx as nx
from shapely.geometry import Point

import numpy as np
import pandas as pd
from tqdm import tqdm
import matplotlib.pyplot as plt

from pyproj import Transformer
from matplotlib.colors import TwoSlopeNorm

from IPython.display import clear_output
from IPython.display import Image

import pickle

import warnings
warnings.filterwarnings(action='ignore')
import sys
sys.stdout = open(os.devnull, 'w')
sys.stderr = open(os.devnull, 'w')
root = os.getcwd()

pd.options.display.float_format = '{:.0f}'.format
plt.rcParams['font.family'] = 'Malgun Gothic'

데이터셋¶

지하철역, 스타벅스 매장, 이디야 매장 공간데이터¶

subway 공간데이터

In [280]:
with open("subway_name.pickle","rb") as fi:
    subway_name = pickle.load(fi) 
subway_name = subway_name.rename(columns={'subway_name' : 'SUBWAY_STA'} )
data_path = os.path.join(root, 'subway_statn_info')
subway = gpd.read_file(os.path.join(data_path,'subway_statn_info.shp'),encoding='EUC-KR')
subway['SUBWAY_STA'] = subway_name['SUBWAY_STA']
subway.head()
Out[280]:
SUBWAY_STA OPNG_YMD SUBWAY__01 geometry
0 온수역 None 57 POINT (184330.338 443625.386)
1 천왕역 None 58 POINT (185637.754 443167.709)
2 남구로역 None 59 POINT (190001.728 442926.56)
3 구로디지털단지역 20070807 60 POINT (191231.554 442905.09)
4 도림천역 None 142 POINT (189654.644 446092.355)
In [283]:
# 지하철역 좌표추출
subway = subway.to_crs(epsg=5179) # 좌표계 변환 
sub_crds = [[list(subway.geometry[i].coords)[0][0], list(subway.geometry[i].coords)[0][1]] for i in range(len(subway))]
sub_crds_arr = np.array(sub_crds)

스타벅스 이디야 공간데이터

In [415]:
ediya = pd.read_csv('ediya.csv')
starbucks = pd.read_csv('starbucks.csv')
In [416]:
# 좌표계 변환 
transformer = Transformer.from_crs("epsg:4326", "epsg:5179", always_xy=True)
ediya['longitude'],ediya['latitude'] = transformer.transform(ediya['lng'],ediya['lat'])
starbucks['longitude'],starbucks['latitude'] = transformer.transform(starbucks['lng'],starbucks['lat'])
In [417]:
ediya = ediya[['gu','title','address','lat','lng','longitude','latitude']]
geometry = [Point(xy) for xy in zip(ediya['longitude'], ediya['latitude'])]
ediya_geo = gpd.GeoDataFrame(ediya, geometry=geometry)
ediya_geo.head()
Out[417]:
gu title address lat lng longitude latitude geometry
0 강남구 강남YMCA점 서울 강남구 논현동 38 127 958615 1946147 POINT (958615.456 1946146.863)
1 강남구 강남구청역아이티웨딩점 서울 강남구 학동로 338 (논현동, 강남파라곤) 38 127 959362 1946462 POINT (959361.721 1946461.887)
2 강남구 강남논현학동점 서울 강남구 논현로131길 28 (논현동) 38 127 958249 1946316 POINT (958248.791 1946316.358)
3 강남구 강남대치점 서울 강남구 역삼로 415 (대치동, 성진빌딩) 38 127 960431 1944780 POINT (960430.89 1944779.522)
4 강남구 강남도산점 서울 강남구 도산대로37길 20 (신사동) 38 127 958600 1947101 POINT (958599.662 1947101.46)
In [418]:
starbucks = starbucks[['구','title','address','lat','lng','longitude','latitude']]
starbucks = starbucks.rename(columns={'구' : 'gu'})
geometry = [Point(xy) for xy in zip(starbucks['longitude'], starbucks['latitude'])]
starbucks_geo = gpd.GeoDataFrame(starbucks, geometry=geometry)
starbucks_geo.head()
Out[418]:
gu title address lat lng longitude latitude geometry
0 강남구 역삼아레나빌딩 서울특별시 강남구 언주로 425 (역삼동) 38 127 959612 1944745 POINT (959612.309 1944744.958)
1 강남구 논현역사거리 서울특별시 강남구 강남대로 538 (논현동) 38 127 957775 1945763 POINT (957774.861 1945762.698)
2 강남구 신사역성일빌딩 서울특별시 강남구 강남대로 584 (논현동) 38 127 957634 1946180 POINT (957634.047 1946179.786)
3 강남구 국기원사거리 서울특별시 강남구 테헤란로 125 (역삼동) 37 127 958588 1944576 POINT (958588.421 1944575.806)
4 강남구 대치재경빌딩 서울특별시 강남구 남부순환로 2947 (대치동) 37 127 961334 1944025 POINT (961333.832 1944024.617)

도로네트워크'와의 매핑¶

도로네트워크 공간데이터

In [288]:
with open('G_utm.pkl', 'rb') as file:
    G_utm = pickle.load(file)

'지하철역 & 스벅/이디야'과 '도로네트워크(G_utm)'와의 매핑

In [289]:
nearest_sub, dist_sub = ox.distance.nearest_nodes(G_utm, X=sub_crds_arr[:,0], Y=sub_crds_arr[:,1], return_dist=True)
nearest_sb, dist_sb      = ox.distance.nearest_nodes(G_utm, X=starbucks['longitude'], Y=starbucks['latitude'], return_dist=True)
nearest_id, dist_id      = ox.distance.nearest_nodes(G_utm, X=ediya['longitude'], Y=ediya['latitude'], return_dist=True)

nearest( G_utm 노드)에 해당하는 G_utm의 index추출

In [291]:
G_utm_nodes = list(G_utm.nodes) 
subway_idx = [G_utm_nodes.index(nearest_sub[i]) for i in range(len(nearest_sub))]
sb_idx = [G_utm_nodes.index(nearest_sb[i]) for i in range(len(nearest_sb))]
id_idx = [G_utm_nodes.index(nearest_id[i]) for i in range(len(nearest_id))]

지하철역 & 두 브랜드 매장 서울 지도(도로네트워크)에 표시¶

In [455]:
gutm_locat_3p(G_utm,starbucks,ediya,sub_crds_arr,'스타벅스','이디야','지하철역','서울특별시 도로네트워크 지하철역,스타벅스,이디야 매장')

1. 구별 스타벅스 이디야 매장 입지환경 분석¶

데이터셋 : 구별 경계 지도 데이터 + 스타벅스&이디야 데이터 + 지하철역 데이터 + 공시지가 데이터¶

구별 경계 지도 데이터

In [293]:
si_file = "./sig_emd/sig_20230729/sig.shp"
sigu = gpd.read_file(si_file, encoding='euckr')
sigu = sigu.set_crs(epsg=5179) # sigu 수동으로 좌표계를 설정

서울만 추출 & 스타벅스&이디야 지하철 데이터 합치기

In [295]:
sigu['CTPRVN_CD'] = [str(num)[:2] for num in sigu['SIG_CD']]
sigu = sigu.loc[sigu['CTPRVN_CD']=='11']
starbucks_count = starbucks_geo.groupby('gu').size().reset_index(name='starbucks_count')
starbucks_count = starbucks_count.rename(columns={'gu' : 'SIG_KOR_NM'} )
ediya_count = ediya_geo.groupby('gu').size().reset_index(name='ediya_count')
ediya_count = ediya_count.rename(columns={'gu' : 'SIG_KOR_NM'} )
sigu = sigu.merge(starbucks_count, on='SIG_KOR_NM')
sigu = sigu.merge(ediya_count, on='SIG_KOR_NM')

스타벅스&이디야 매장 수 차이 변수 생성

In [296]:
sigu['sb_id'] = sigu['starbucks_count']-sigu['ediya_count']
for index, rows in sigu.iterrows():
    if rows['sb_id']>0:
        sigu.at[index, 'sb_id_1']= "SB: +"+str(rows['sb_id'])
    elif rows['sb_id']==0:
        sigu.at[index, 'sb_id_1']= "동일"
    else:
        sigu.at[index, 'sb_id_1']= "ED: +"+str(rows['sb_id']*-1)

공시지가 데이터

In [300]:
with open("rprice.pickle","rb") as fi:
    rprice = pickle.load(fi) 
rprice['공시지가'] = rprice['공시지가'].astype(float)
rprice = rprice[rprice['시도명']=="서울특별시"]
rprice_gu = rprice.groupby('시군구명')['공시지가'].mean().reset_index(name='공시지가 평균')
rprice_gu = rprice_gu.rename(columns={'시군구명' : 'SIG_KOR_NM'} )
sigu = sigu.merge(rprice_gu, on='SIG_KOR_NM')

구별 지하철역 수

In [303]:
gu_sub = pd.read_csv('서울교통공사_자치구별지하철역정보_20240628.csv',encoding='euckr')
gu_sub = gu_sub.rename(columns={'자치구' : 'SIG_KOR_NM'} )
sigu = sigu.merge(gu_sub.drop(columns = ['해당역(호선)']), on='SIG_KOR_NM')
sigu.head()
Out[303]:
SIG_CD SIG_ENG_NM SIG_KOR_NM geometry CTPRVN_CD starbucks_count ediya_count sb_id sb_id_1 공시지가 평균 역개수
0 11110 Jongno-gu 종로구 POLYGON ((956615.453 1953567.199, 956621.579 1... 11 39 35 4 SB: +4 5938143 15
1 11140 Jung-gu 중구 POLYGON ((957890.386 1952616.746, 957909.908 1... 11 52 34 18 SB: +18 9949269 23
2 11170 Yongsan-gu 용산구 POLYGON ((953115.761 1950834.084, 953114.206 1... 11 24 13 11 SB: +11 6812485 10
3 11200 Seongdong-gu 성동구 POLYGON ((959681.109 1952649.605, 959842.412 1... 11 14 20 -6 ED: +6 4884766 14
4 11215 Gwangjin-gu 광진구 POLYGON ((964825.058 1952633.25, 964875.565 19... 11 19 20 -1 ED: +1 4371127 11

1) 서울 구별 평균 공시지가 COLORMAP¶

In [335]:
# 공시지가 평균 - 구 평균, 구 최소, 구 최대
round(sigu['공시지가 평균'].mean()),round(sigu['공시지가 평균'].min()),round(sigu['공시지가 평균'].max())
Out[335]:
(4668753, 2390374, 11925742)
In [481]:
add_text_sb = "평균 공시지가가 높을수록 붉은색, 낮을수록 파랑색"
title_text = "서울 구별 평균 공시지가"
map_color_text(sigu,'공시지가 평균','coolwarm','평균 공시지가 최소값 ~ 최대값 ( 단위:천만원 )','SIG_KOR_NM',add_text_sb,title_text)

2) 서울 구별 지하철역 수 COLORMAP¶

In [482]:
add_text_sb = '역개수가 더 많을수록 붉은색, 적을수록 파랑색'
title_text = '서울 구별 지하철역 수 COLORMAP'
map_color_text(sigu,'역개수','coolwarm','역개수 최소값 ~ 최대값','SIG_KOR_NM',add_text_sb,title_text)

3) 서울 구별 '스타벅스'&'이디야' 매장 수 차이 COLORMAP¶

스타벅스 이디야 매장수 차이

In [305]:
starbucks_geo.shape,ediya_geo.shape # 이디야가 72개 더 많다.
Out[305]:
((614, 8), (686, 8))
In [483]:
add_text_sb = '스타벅스(SB)가 더 많을수록 붉은색, 이디야(ED)가 더 많을수록 파랑색'
title_text = "서울 구별 '스타벅스'&'이디야' 매장 수 차이"
map_color_text(sigu,'sb_id','coolwarm','매장 수 차이 최소값 ~ 최대값','sb_id_1',add_text_sb,title_text)

1)~3) 종합 분석¶

In [457]:
Image('seoul_sb_ed01.png')
Out[457]:

공시지가가 높은 구 그리고, 지하철역이 많은 구에 스타벅스 매장 수가 이디야보다 더 많다.¶

2. 스타벅스 & 이디야 매장에서 지하철역까지의 최단거리 분석 ( 각 매장에서 1000미터 이내 )¶

스타벅스 최근접 지하철역 & 거리

In [308]:
starbucks_1 = nearest_fun(G_utm,nearest_sb,nearest_sub,starbucks)

이디야 최근접 지하철역 & 거리

In [309]:
ediya_1 = nearest_fun(G_utm,nearest_id,nearest_sub,ediya)

구별 평균 최단거리 생성 & 데이터셋 합치기¶

In [314]:
sb_gu_mean = starbucks_1.groupby('gu')['dist2sub'].mean().reset_index()
sb_gu_mean = sb_gu_mean.sort_values(by='dist2sub', ascending=True)
id_gu_mean = ediya_1.groupby('gu')['dist2sub'].mean().reset_index()
id_gu_mean = id_gu_mean.sort_values(by='dist2sub', ascending=True)
sb_gu_mean = sb_gu_mean.rename(columns={'gu' : 'SIG_KOR_NM'} )
id_gu_mean = id_gu_mean.rename(columns={'gu' : 'SIG_KOR_NM'} )
sb_gu_mean = sb_gu_mean.rename(columns={'dist2sub' : '평균거리_sb'} )
id_gu_mean = id_gu_mean.rename(columns={'dist2sub' : '평균거리_ed'} )
sigu = sigu.merge(sb_gu_mean, on='SIG_KOR_NM')
sigu = sigu.merge(id_gu_mean, on='SIG_KOR_NM')
# 이디야 최단거리(평균) - 스타벅스 최단거리(평균)
sigu['평균거리_차이'] = sigu['평균거리_ed']-sigu['평균거리_sb']
sigu.head()
Out[314]:
SIG_CD SIG_ENG_NM SIG_KOR_NM geometry CTPRVN_CD starbucks_count ediya_count sb_id sb_id_1 공시지가 평균 역개수 평균거리_sb 평균거리_ed 평균거리_차이
0 11110 Jongno-gu 종로구 POLYGON ((956615.453 1953567.199, 956621.579 1... 11 39 35 4 SB: +4 5938143 15 404 429 25
1 11140 Jung-gu 중구 POLYGON ((957890.386 1952616.746, 957909.908 1... 11 52 34 18 SB: +18 9949269 23 377 415 38
2 11170 Yongsan-gu 용산구 POLYGON ((953115.761 1950834.084, 953114.206 1... 11 24 13 11 SB: +11 6812485 10 496 530 34
3 11200 Seongdong-gu 성동구 POLYGON ((959681.109 1952649.605, 959842.412 1... 11 14 20 -6 ED: +6 4884766 14 396 469 73
4 11215 Gwangjin-gu 광진구 POLYGON ((964825.058 1952633.25, 964875.565 19... 11 19 20 -1 ED: +1 4371127 11 368 580 212

1) 스타벅스 매장에서 지하철역까지 최단거리 구별 평균 COLORMAP¶

In [484]:
add_text_sb = '최단거리(평균)가 짧을수록 파랑색, 길수록 붉은색'
title_text = '스타벅스 매장에서 지하철역까지 최단거리 구별 평균 COLORMAP'
map_color_text(sigu,'평균거리_sb','coolwarm','최단거리 평균 최소값~최대값','SIG_KOR_NM',add_text_sb,title_text)

2) 이디야 매장에서 지하철역까지 최단거리 구별 평균 COLORMA¶

In [485]:
add_text_sb = '최단거리(평균)가 짧을수록 파랑색, 길수록 붉은색'
title_text = '이디야 매장에서 지하철역까지 최단거리 구별 평균 COLORMAP'
map_color_text(sigu,'평균거리_ed','coolwarm','최단거리 평균 최소값~최대값','SIG_KOR_NM',add_text_sb,title_text)

3) 이디야 최단거리(평균) & 스타벅스 최단거리(평균) 차이 COLORMAP¶

In [318]:
sigu['평균거리_ed'].mean(),sigu['평균거리_sb'].mean(),sigu['평균거리_차이'].mean()
Out[318]:
(583.5464143802974, 464.65921912733825, 118.8871952529592)

이디야의 평균 최단거리가 스타벅스보다 119m 더 길다.

In [486]:
add_text_sb = '이디야 최단거리(평균)가 스타벅스보다 길수록 붉은색, 짧을수록 파랑색'
title_text = '이디야 최단거리(평균) & 스타벅스 최단거리(평균) 차이 COLORMAP'
map_color_text1(sigu,'평균거리_차이','coolwarm','최단거리 평균 차이 최소값~최대값','SIG_KOR_NM',add_text_sb,title_text)

1)~3) 종합 분석¶

In [456]:
Image('seoul_sb_ed02.png')
Out[456]:

두 브랜드 공통적으로 강북에 위치한 구들에서 지하철역까지의 최단거리(평균)가 짧다.¶

강남에 위치한 구들에서는 강북에 비해 최단거리(평균)가 길며, 특히 스타벅스가 더 뚜렷한 양상이 나타난다.¶

서울 대부분의 구에서 스타벅스가 이디야보다 지하철역까지의 최단거리(평균)가 더 짧다.¶

공시지가가 높고 지하철역이 많은 구에서는 차이가 매우 작게 나타난다.(종로,중구,용산,강남,송파)¶

3. 최단경로 도로네트워크 지도상 확인¶

두 브랜드의 매장 수가 가장 많은 강남구

In [206]:
with open('G_gang.pkl', 'rb') as file:
    G_gang = pickle.load(file)
In [326]:
subname_gang = ['삼성역','선릉역','역삼역','강남역','압구정역','신사역','매봉역','도곡역','대치역','학여울역','대청역','일원역','수서역','청담역','강남구청역','학동역','논현역','언주역','선정릉역','삼성중앙역','봉은사역']
subway_gang = subway[ subway['SUBWAY_STA'].isin(subname_gang) ]
sub_gang_arr = sub_crds_arr[subway_gang.index]
starbucks_gang = starbucks[starbucks['gu']=='강남구']
ediya_gang = ediya[ediya['gu']=='강남구']
In [338]:
round(starbucks_gang['dist2sub'].mean()),round(ediya_gang['dist2sub'].mean())
Out[338]:
(489, 553)

강남구의 경우 이디야의 최단거리(평균)가 스타벅스보다 64m 더 길다.큰 차이가 없다.

In [327]:
gnode_near_vi(G_gang,sub_gang_arr,starbucks_gang,"강남구","(스타벅스)")
gnode_near_vi(G_gang,sub_gang_arr,ediya_gang,"강남구","(이디야)")

함수¶

최근접 지하철역 노드, 거리 반환¶

In [3]:
def nearest_fun(G_utm,nearest_sb,nearest_sub,df):
    shortest_dist2sub = [] 
    shortest_dist2sub_p = [] 
    for i in tqdm(range(len(nearest_sb))): 
        centroid_point = (G_utm.nodes[nearest_sb[i]]['x'], G_utm.nodes[nearest_sb[i]]['y']) 
        buffer = Point(centroid_point).buffer(1000) 
        # 1000미터 이내의 지하철역 찾기 ======================================================================
        temp = [] 
        temp_sub = [] 
        for j in range(len(nearest_sub)): 
            subway_point_xy = (G_utm.nodes[nearest_sub[j]]['x'], G_utm.nodes[nearest_sub[j]]['y']) 
            if buffer.contains(Point(subway_point_xy)):
                try: 
                    dist = nx.shortest_path_length(G_utm, nearest_sb[i], nearest_sub[j],weight='length')
                    temp.append(dist)
                    temp_sub.append(nearest_sub[j])
                except: 
                    pass
        if len(temp) > 0 : 
            shortest_dist2sub.append(min(temp))
            shortest_dist2sub_p.append(temp_sub[temp.index(min(temp))])       
        else: 
            shortest_dist2sub.append(None)
            shortest_dist2sub_p.append(None)

    df['dist2sub'] = shortest_dist2sub   
    df['dist2sub_p'] = shortest_dist2sub_p
    return(df)

최근접 지하철역 경로 시각화¶

In [201]:
def nearest_vi_1(G_utm,nearest,nearest_sub,size1,size2,nd_color,inout,range1,mark_size1,mark_size2,mk_color1,mk_color2,rou_alpha,gu,add_text ):
    import matplotlib.cm as cm
    import matplotlib.colors as mcolors
    
    viewer = inout
    if viewer=='out':
        %matplotlib tk  
    if viewer=='in':
        %matplotlib inline         
    fig, ax = plt.subplots(figsize=(size1,size2))
    ox.plot_graph(G_utm, ax=ax, node_size=0, edge_color='gray', show=False, close=False)

    # 컬러맵 설정
    cmap = cm.get_cmap(nd_color)
    norm = mcolors.Normalize(vmin=0, vmax= range1 )  
    for i in range(len(nearest)):
        centroid_point = (G_utm.nodes[nearest[i]]['x'], G_utm.nodes[nearest[i]]['y'])
        buffer = Point(centroid_point).buffer(range1)
        temp = []
        temp_sub = []

        for j in range(len(nearest_sub)):
            subway_point_xy = (G_utm.nodes[nearest_sub[j]]['x'], G_utm.nodes[nearest_sub[j]]['y'])
            if buffer.contains(Point(subway_point_xy)):
                try:
                    dist = nx.shortest_path_length(G_utm, nearest[i], nearest_sub[j], weight='length')
                    temp.append(dist)
                    temp_sub.append(nearest_sub[j])
                except:
                    pass

        if len(temp) > 0:
            shortest_path = nx.shortest_path(G_utm, nearest[i], temp_sub[temp.index(min(temp))], weight='length')
            path_length = temp[temp.index(min(temp))]
            color = cmap(norm(path_length))  
            ox.plot_graph_route(G_utm, shortest_path, ax=ax,route_alpha=rou_alpha , route_linewidth=3, route_color=color,orig_dest_size=0, show=False, close=False)

    nearest_x = [G_utm.nodes[nearest[idx]]['x'] for idx in range(len(nearest)) ]
    nearest_y = [G_utm.nodes[nearest[idx]]['y'] for idx in range(len(nearest)) ]
    ax.scatter(nearest_x,nearest_y, color='black', s=mark_size1, alpha=1, zorder=5, edgecolor=mk_color1,label='매장')

    nearest_sub_x = [G_utm.nodes[nearest_sub[idx]]['x'] for idx in range(len(nearest_sub)) ]
    nearest_sub_y = [G_utm.nodes[nearest_sub[idx]]['y'] for idx in range(len(nearest_sub)) ]
    ax.scatter(nearest_sub_x,nearest_sub_y, color='white', s=mark_size2, alpha=1, zorder=5, edgecolor=mk_color2,label='지하철역')
    plt.legend(loc='upper right')
    plt.title('서울특별시 '+gu+'의 각 매장에서 지하철역까지의 최단 경로')
    plt.colorbar(cm.ScalarMappable(norm=norm, cmap=cmap), ax=ax, label='Distance to Subway (meters)',shrink=0.25) # shrink 막대그래프 범례 크기
    plt.text(0.5,0.98, add_text, ha='center', va='center', transform=ax.transAxes, fontsize=12)
    plt.show()
In [202]:
def gnode_near_vi(G_mapo,sub_mapo_arr,starbucks_mapo,gu,add_text):
    n_mapo_sub, d_mapo_sub = ox.distance.nearest_nodes(G_mapo, X=sub_mapo_arr[:,0], Y=sub_mapo_arr[:,1], return_dist=True)
    n_mapo_sb, d_mapo_sb      = ox.distance.nearest_nodes(G_mapo, X=starbucks_mapo['longitude'], Y=starbucks_mapo['latitude'], return_dist=True)
    nearest_vi_1(G_mapo,n_mapo_sb,n_mapo_sub,16,9,'bwr_r','in',1000,20,20,'white','black',1,gu,add_text)

도로네트워크지도 + 지점위치

In [454]:
def gutm_locat_3p(G_utm,starbucks,ediya,sub_crds_arr,label1,label2,label3,title):
    import matplotlib.cm as cm
    import matplotlib.colors as mcolors

    fig, ax = plt.subplots(figsize=(12, 12))
    ox.plot_graph(G_utm, ax=ax, node_size=0, edge_color='gray',edge_linewidth=0.25, show=False, close=False)
    cmap = cm.get_cmap('Reds_r')# 진한 붉은색에서 연한 붉은색으로,'Reds' : 연한 붉은색에서 진한 붉은색으로
    norm = mcolors.Normalize(vmin=0, vmax=1000)  # 1000 미터를 기준으로 정규화
    ax.scatter( starbucks['longitude'],starbucks['latitude'], color='red', s=15, alpha=1, zorder=1,label=label1)
    ax.scatter( ediya['longitude'],ediya['latitude'], color='green', s=15, alpha=1, zorder=1,label=label2)
    ax.scatter(sub_crds_arr[:, 0], sub_crds_arr[:, 1], color='white', s=15, alpha=1, zorder=1, edgecolor='black',label=label3)
    plt.legend(loc='upper right')

    plt.title(title)
    plt.show()

변수에 따른 맵 구별 색상 변화 + TEXT¶

In [478]:
def map_color_text(sigu,var,colorm,cbar_label,var1,additional_text,title ):
    from matplotlib.colors import TwoSlopeNorm
    norm = TwoSlopeNorm(vmin=min(sigu[var]), vcenter =sigu[var].median() , vmax=max(sigu[var]))

    # 시각화
    fig, ax = plt.subplots(1, 1, figsize=(10,7))
    base = sigu.plot(column=var, ax=ax, legend=False, cmap=colorm, edgecolor='k', linewidth=0.5, norm=norm)

    sm = plt.cm.ScalarMappable(cmap=colorm, norm=norm)
    sm._A = [] 
    cbar = fig.colorbar(sm, ax=ax, shrink=0.25)  # shrink 매개변수로 높이 축소
    cbar.set_label(cbar_label, fontsize=8, weight='bold')

    for idx, row in sigu.iterrows():
        plt.text(row.geometry.centroid.x, row.geometry.centroid.y,row[var1],#"test",
                 horizontalalignment='center', fontsize=8, color='black', weight='bold')

    plt.text(0.5,0.98, additional_text, ha='center', va='center', transform=ax.transAxes, fontsize=10)
    ax.set_axis_off()
    ax.set_title(title, fontsize=12, weight='bold')
    plt.show()
In [479]:
def map_color_text1(sigu,var,colorm,cbar_label,var1,additional_text,title ):
    from matplotlib.colors import TwoSlopeNorm
    norm = TwoSlopeNorm(vmin=min(sigu[var]), vcenter = 0 , vmax=max(sigu[var]))

    fig, ax = plt.subplots(1, 1, figsize=(10,7))
    base = sigu.plot(column=var, ax=ax, legend=False, cmap=colorm, edgecolor='k', linewidth=0.5, norm=norm)

    sm = plt.cm.ScalarMappable(cmap=colorm, norm=norm)
    sm._A = [] 
    cbar = fig.colorbar(sm, ax=ax, shrink=0.25)  
    cbar.set_label(cbar_label, fontsize=8, weight='bold')

    for idx, row in sigu.iterrows():
        plt.text(row.geometry.centroid.x, row.geometry.centroid.y,row[var1],#"test",
                 horizontalalignment='center', fontsize=8, color='black', weight='bold')
    plt.text(0.5,0.98, additional_text, ha='center', va='center', transform=ax.transAxes, fontsize=10)
    ax.set_axis_off()
    ax.set_title(title, fontsize=12, weight='bold')
    plt.show()